<?php
namespace app\api\controller;
use think\Db;
use think\Log;

/**
 * 刷脸设备接口
 */
class Device extends Base
{

    public function test() {
        
        // 2020-08-25 19:00:47
        $par_add_time = '2020-10-06 16:09:16';date('Y-m-d H:i:s',time());
        $date1 = date("Y-m-d",strtotime ('2020-10-04 16:09:16'));
        $date2 = date ("Y-m-d");
        $diff = (strtotime ($date2) - strtotime($date1)) / (60 * 60 * 24);

        $oldFansDays = DB::name('partner_class')->where(['class_id'=>1])->value('class_fans_days');
        $newFansDays = 60;
        if ($diff > $oldFansDays) {
            $diff = $newFansDays - $oldFansDays;
        } else {
            $diff = $diff - $newFansDays;
        }

        $par_add_time2 = date("Y-m-d H:i:s",strtotime("+{$diff} day",strtotime ($par_add_time)));


        return json(['msg'=>'ok','data'=>['$date1'=>$date1, '$date2'=>$date2, '$diff'=>$diff, '$par_add_time'=>$par_add_time2] ]);
    }

    private function checkAccess()
    {
        // 请求头
        $time = request()->header('X-Access-Time');
        $sign = request()->header('X-Access-Sign');
        Log::record($time,'time');
        Log::record($sign,'sign');
        $posts = input('post.');
        Log::record($posts, 'posts');

        // key排序
        ksort($posts);
        $buff = "";
        foreach ($posts as $k => $v)
        {
            $buff .= $k . "=" . $v . "&";
        }
        Log::record($buff, 'buff');

        if (!isset($time) || !isset($sign)) {
            return false;
        }
        $appId      = "A6076388312688";
        $appkey     = "9AF007B0-BE92-F501-6998-6D57B9CCE8B9";

        $source = $appId . '&' . $buff . $appkey . '&' . $time;

        Db::name('device_log')->insert([
            'dl_ip'=>request()->ip(),
            'dl_url'=>request()->url(),
            'dl_source'=>$source,
            'aaa'=>$time . $sign,
            'dl_add_time'=>date('Y-m-d H:i:s',time())
        ]);

        Log::record($source, 'buff');

        $calSign = md5($source);
        Log::record($calSign, 'buff');

        return $sign == $calSign;
    }

    private function outputFail($msg) {
        return json(['code'=>0, 'msg'=>$msg, 'data'=>null]);
    }

    private function outputSucc($msg, $data = null) {
        return json(['code'=>1, 'msg'=>$msg, 'data'=>$data]);
    }

    private function outputAccessFail() {
        return json(['code'=>0, 'msg'=>'非法请求', 'data'=>null]);
    }

    /**
     * 获取用户信息，如果没有就创建
     * $userPhone
     * $shopId
     * $wxFaceId
     * $code
     */
    public function userBind() 
    {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(!preg_match("/^1[3456789]\d{9}$/", $userPhone)) {
            return $this->outputFail('手机号格式错误');
        }
        if(empty($shopId) || empty($code) || empty($userPhone) || empty($wxFaceId)){
            return $this->outputFail('参数错误');
        }
        $phonecode = Db::name('phonecode')->where(['phone'=>$userPhone,'status'=>0,'type'=>3])->find();
        if(empty($phonecode)){
            return $this->outputFail('请先发送验证码');
        }
        $diff = time() - $phonecode['time'];
        if($diff >= 30*60){
            return $this->outputFail('验证码已失效');
        }
        if($code != $phonecode['code']){
            return $this->outputFail('验证码输入错误');
        }
        Db::name('phonecode') ->where('id', $phonecode['id'])->setField ('status',1);

        $user = Db::name('u_user')->where(['user_phone'=>$userPhone])
            ->field("user_id userId, user_level userLevel, user_integral userIntegral")
            ->find();
        if (!empty($user)) {
            $user['isNew'] = false;
            Db::name('u_user') ->where('user_id', $user['userId'])->setField('user_wx_face_id', $wxFaceId);
            return $this->outputSucc('ok', $user);
        }
        
        Db::startTrans ();
        try{
            // 注册用户
            $user_id = Db::name('u_user')->insertGetId([
                'user_phone'=>$userPhone,
                'user_wx_face_id'=>$wxFaceId,
                'user_username'=>$userPhone,
                'user_time'=>date('Y-m-d H:i:s')
            ]);
        
            $give = Db::name('jifen_conf')->where('conf_id',16)->value('conf_rate');
            $form = Db::name('u_user u')->join('shop s','u.user_id = s.shop_user_id','left')
                ->where(['s.shop_id'=>$shopId])
                ->find();
            if(empty($form)){
                return $this->outputFail('商铺不存在');
            }
            if($form['user_area'] == ''){
                Db::name('u_user')->where(['user_id'=>$form['user_id']])->update (['user_province'=>1055,'user_city'=>1065,'user_area'=>1134]);
                $form['user_area'] = 1134;
            }else{
                // 邀请人注册区没有代理
                $is_qu = DB::name('admin')->where(['area'=>$form['user_area']])->find();
                if (empty($is_qu)) {
                    $form['user_area'] = 1134;
                }
            }
            
            //如果邀请方是合伙人另外奖励
            $is_partner = DB::name('partner')
                            ->where(['par_user_id'=>$form['user_id'],'par_cancel'=>0])
                            ->find();
            if (!empty($is_partner)) {
                // 添加推荐人
                DB::name('u_user')->where(['user_id'=>$user_id])->update(['user_recommend'=>$form['user_id']]);
                // 该级别合伙人推荐粉丝奖励有效时间
                $invite_days = DB::name('partner_class')
                                ->where(['class_id'=>$is_partner['par_class_id']])
                                ->value('class_fans_days');
                // 邀请粉丝每天不能超过100位，超过没有奖励
                $fans_count = DB::name('u_user')
                            ->where(['user_recommend'=>$form['user_id']])
                            ->whereTime('user_time','today')
                            ->count();
                if ($fans_count < 100) {
                    if (time() < (strtotime($is_partner['par_add_time'])+3600*24*$invite_days)) {
                        // 合伙人一段时间内邀请粉丝积分奖励
                        $give_jifen = DB::name('partner_class')
                                    ->where(['class_id'=>$is_partner['par_class_id']])
                                    ->value('class_fans_jifen_reg');
                        // 合伙人邀请粉丝获得的奖励
                        $this->par_fans($user_id,3,1,$user_id);
                        // 记录获得积分
                        // DB::name('jifen_consume')->insert(['consume_content'=>'合伙人邀请好友注册获得'.$give_jifen.'积分','consume_user_id'=>$form['user_id'],'consume_add_time'=>date('Y-m-d H:i:s')]);
                        // // 添加提示
                        // Db::name('notice')->insert (['n_to'=>1,'n_title'=>'合伙人邀请好友','n_content'=>'邀请好友注册获得'.$give_jifen.'积分','n_images'=>'','n_type'=>3,'n_user_id'=>$form['user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s'),'n_where_id'=>'']);
                        // $this->jpushUser(1,$form['user_id'],'合伙人邀请好友注册获得'.$give_jifen.'积分',json([]));
                    }else{
                        // 合伙人邀请粉丝获得的奖励
                        $this->par_fans($user_id,3,1,$user_id);
                    }
                }else{
                    // 添加提示
                    Db::name('notice')->insert (['n_to'=>1,'n_title'=>'合伙人邀请好友','n_content'=>'当日邀请好友已达上限','n_images'=>'','n_type'=>3,'n_user_id'=>$form['user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s'),'n_where_id'=>'']);
                    $this->jpushUser(1,$form['user_id'],'当日邀请好友已达上限',json([]));
                }
            }else{
                Db::name('admin')->where('area',$form['user_area'])->setDec('integral',$give);
                $this->jifenFlow($give,$form['user_area'],$form['user_id'],'register');

                Db::name('jifen_consume')->insert(['consume_content'=>'邀请好友获得'.$give.'积分','consume_user_id'=>$form['user_id'],'consume_add_time'=>date('Y-m-d H:i:s')]);

                Db::name('notice')->insert (['n_to'=>1,'n_title'=>'邀请好友','n_content'=>'邀请好友获得'.$give.'积分','n_images'=>'','n_type'=>3,'n_user_id'=>$form['user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s'),'n_where_id'=>'']);

                $this->jpushUser(1,$form['user_id'],'邀请好友获得'.$give.'积分',json([]));
            }
            // 邀请的注册直接成为好友
            $focus = Db::name('user_fellow')->where(['fellow_user_id'=>$user_id,'fellow_star_user_id'=>$form['user_id']])->find();
            if(!empty($focus)){
                return $this->outputFail('已关注该好友');
            }
            $time = date('Y-m-d H:i:s');
            $param = [
                [
                    'fellow_user_id'=>$user_id,
                    'fellow_star_user_id'=>$form['user_id'],
                    'fellow_add_time'=>$time
                ],
                [
                    'fellow_user_id'=>$form['user_id'],
                    'fellow_star_user_id'=>$user_id,
                    'fellow_add_time'=>$time
                ]
            ];
            $res = Db::name('user_fellow')->insertAll ($param);
            if($res){
                Db::name('u_user')->where('user_id',$form['user_id'])->setInc('user_fans');
                Db::name('u_user')->where('user_id',$user_id)->setInc('user_attention');
            }
            Db::commit ();
            return $this->outputSucc('ok', ["isNew"=>true, 'userId'=>$user_id, 'userLevel'=>1, 'userIntegral'=>0]);
        } catch (\Exception $e){
            Db::rollback ();
            Log::record($e->getMessage(),'error');
            return $this->outputFail('交易失败');
        }

    }

    /**
     * 获取用户信息
     * $wxFaceId
     */
    public function userFace() 
    {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(empty($wxFaceId)){
            return $this->outputFail('参数错误');
        }
        $user = Db::name('u_user')->where(['user_wx_face_id'=>$wxFaceId])
            ->field("user_id userId, user_level userLevel, user_integral userIntegral")
            ->find();
        if (!empty($user)) {
            return $this->outputSucc('ok', $user);
        }

        return $this->outputFail('未找到');
    }

    /**
     * 积分交易
     * $userId 
     * $shopId
     * $integral
     */
    public function jifenTrade() 
    {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if (empty($userId) || empty($shopId) || empty($integral) || 0 > $integral) {
            return $this->outputFail('参数错误');
        }
        
        Db::startTrans ();
        try{
            $order = $this->getOrderNumber ();
            $param = [
                'record_number'=>$order,
                'record_user_id'=>$userId,
                'record_shop_id'=>$shopId,
                'record_type'=>2,
                'record_payment_type'=>0,
                'record_status'=>1,
                'record_jifen'=>$integral,
                'record_money'=>0,
                'record_remark'=>'',
                'record_add_time'=>date("Y-m-d H:i:s"),
                'record_give_jifen'=>0,
                'record_lose_time'=>date("Y-m-d H:i:s",strtotime ("+15 minutes"))
            ];
            $record_id = Db::name('record')->insertGetId ($param);
            
            $shop = Db::name('shop')->where(['shop_id'=>$shopId])->find();
            $back = $this->consume($userId,$integral,$shopId);
            $rate = Db::name('jifen_conf')->where('conf_id',2)->value ('conf_rate');
            if($back['status'] == 100){
                Db::rollback ();
                return $this->outputSucc('积分不足');
            }else{
                Db::name('jifen_consume')->insert (['consume_content'=>'积分支付给“'.$shop['shop_name'].'”'.$integral.'积分','consume_user_id'=>$userId,'consume_add_time'=>date("Y-m-d H:i:s")]);
                Db::name('record')->where(['record_id'=>$record_id])->update(['record_status'=>2,'record_pay_time'=>date("Y-m-d H:i:s"),'record_shop_balance'=>$shop['shop_balance']+$integral*$rate,'record_money'=>$integral*$rate]);
                Db::name('shop')->where('shop_id',$shopId)->setInc ('shop_balance',$integral*$rate);
                Db::name('shop')->where('shop_id',$shopId)->setInc('shop_all_balance',$integral * $rate);
                try{
                    $this->jpushShop(1,$shopId,"收款{$integral}积分",json([]));
                }catch (\Exception $e){
                    Log::record($e->getMessage(),'error');
                }
                Db::commit ();
                $res = [];
                $res['profit'] = $integral * $rate;
                return $this->outputSucc('交易成功', $res);
            }
        }catch (\Exception $e){
            Db::rollback ();
            Log::record($e->getMessage(),'error');
            return $this->outputFail('交易失败');
        }

    }

    /**
     * 获取商品信息
     * $orderNum  订单号
     */
    public function scanExchange()
    {

        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if (empty($orderNum) || empty($shopId)) {
            return $this->outputFail('参数错误');
        }
        $order = Db::name('order')
            ->where(['o_order_num'=>$orderNum])
            ->find();

        if($order['o_shop_id'] != $shopId){
            return $this->outputFail('订单不存在或已兑换');
        }

        $orderInfo = Db::name('order_info')
            ->where('oi_order_id', $order['o_id'])
            ->field([
                'oi_goods_name goodsName',
                'oi_goods_image goodsImage',
                'oi_goods_price goodsPrice',
                'oi_goods_jifen goodsIntegral',
                'oi_total_price goodsTotalPrice',
                'oi_goods_model goodsUnit',
                'oi_num goodsNum'
            ])
            ->select();
        return $this->outputSucc('ok', $orderInfo);
    }

    /**
     * 确认兑换
     */
    public function doExchange() {

        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if (empty($orderNum)) {
            return $this->outputFail('参数错误');
        }
        $order = Db::name('order')
            ->where(['o_order_num'=>$orderNum])
            ->find();
        if(empty($order) || $order['o_status'] != 10){
            return $this->outputFail('商品已兑换');
        }
        $o_id = $order['o_id'];
        Db::startTrans ();
        try{
            Db::name('order')->where(['o_id'=>$o_id])->setField ('o_status',4);
            if($order['o_esp'] == 1){
                $order_info = Db::name('order_info')->where('oi_order_id',$order['o_id'])->select ();
                $rat = Db::name('jifen_conf')->where('conf_id',1)->value('conf_rate');
                foreach($order_info as $ss){
                    $give = Db::name('product')->where('p_id',$ss['oi_goods_id'])->find();
                    if($give['p_give'] > 0){
                        $qu = Db::name('shop')->where('shop_id',$give['p_shop_id'])->value('shop_qu_id');

                        Db::name('shop')->where('shop_id',$give['p_shop_id'])->dec('shop_integral',$give['p_give'] * $ss['oi_num'])->dec('shop_pledge_money',($give['p_give'] * $ss['oi_num'])*$rat)->update();

                        Db::name('order')->insert(['o_type'=>5,'o_order_num'=>$this->getOrderNumber (),'o_money'=>($give['p_give'] * $ss['oi_num'])*$rat,'o_jifen'=>'','o_status'=>5,'o_pay_status'=>2,'o_shop_id'=>$give['p_shop_id'],'o_add_time'=>date('Y-m-d H:i:s')]);

                        $this->jifenFlow($give['p_give']* $ss['oi_num'],$qu,$order['o_user_id'],'exchange');

                        Db::name('jifen_consume')->insert(['consume_content'=>'购买商品赠送'.$give['p_give'] * $ss['oi_num'].'积分','consume_user_id'=>$order['o_user_id'],'consume_add_time'=>date('Y-m-d H:i:s')]);
                        Db::name('notice')->insert (['n_to'=>1,'n_title'=>'购买商品','n_content'=>'购买商品赠送'.$give['p_give'] * $ss['oi_num'].'积分','n_images'=>'','n_type'=>2,'n_user_id'=>$order['o_user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s')]);
                        $this->jpushUser(1,$order['o_user_id'],'购买商品赠送'.$give['p_give'] * $ss['oi_num'].'积分',json([]));
                    }
                }
                if($order['o_money'] > 0){
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_balance',$order['o_money']);
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_all_balance',$order['o_money']);

                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setDec ('shop_balance_yet',$order['o_money']);

                    // 店铺现金交易额
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_money_balance',$order['o_money']);
                    // 店铺当日现金交易额// 定时任务，每日0点清空
                    DB::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_today_balance',$order['o_money']);
                    // 店铺现金交易1‰分红
                    $shop_user_id   = DB::name('shop')
                                    ->where('shop_id',$order['o_shop_id'])
                                    ->value('shop_user_id');
                    $this->shop_profit($order['o_shop_id'],$shop_user_id,$order['o_money'],3);

                    // Db::name('admin')->where('id',1)->setDec ('balance',$order['o_money']);
                }
                if($order['o_jifen'] > 0){
                    $rat = Db::name('jifen_conf')->where('conf_id',2)->value('conf_rate');
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setDec ('shop_balance_yet',$order['o_jifen'] * $rat);
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc('shop_balance',$order['o_jifen'] * $rat);
                    Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc('shop_all_balance',$order['o_jifen'] * $rat);
                }
            }else if($order['o_esp'] == 2){
                Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_balance',$order['o_esp_money']);
                Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_all_balance',$order['o_esp_money']);

                Db::name('shop')->where('shop_id',$order['o_shop_id'])->setDec ('shop_balance_yet',$order['o_esp_money']);
                // 店铺现金交易额
                Db::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_money_balance',$order['o_esp_money']);
                // 店铺当日现金交易额// 定时任务，每日0点清空
                DB::name('shop')->where('shop_id',$order['o_shop_id'])->setInc ('shop_today_balance',$order['o_esp_money']);
                // 店铺现金交易1‰分红
                $shop_user_id   = DB::name('shop')
                                ->where('shop_id',$order['o_shop_id'])
                                ->value('shop_user_id');
                $this->shop_profit($order['o_shop_id'],$shop_user_id,$order['o_esp_money'],3);
            }

            Db::name('notice')->insert (['n_to'=>1,'n_title'=>'购物订单','n_content'=>'订单兑换，等待买家评价','n_images'=>'','n_type'=>2,'n_user_id'=>$order['o_user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s')]);
            $this->jpushUser(1,$order['o_user_id'],'订单订单兑换，等待买家评价',json([]));
            Db::commit ();
            $res = [];
            $res['score'] = $order['o_jifen'];// 积分
            $res['money'] = $order['o_money'];// 金额
            return $this->outputSucc('兑换成功', $res);
        }catch (\Exception $e){
            Db::rollback ();
            return $this->outputFail('兑换失败');
        }
    }

    /**
     * 获取广告
     * 
     */
    public function getAd()
    {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        $ad = Db::name('jifen_conf')
            ->where(['conf_id'=>44])
            ->find();
        return $this->outputSucc('ok', $ad['conf_img']);
    }

    /**
     * 发送验证码
     * $phone
     */
    public function sendVerifyCode(){
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(!isset($phone) ){
            return $this->outputFail('请输入手机号');
        }
        $num = GetRandCode(6);
        if(!preg_match("/^1[3456789]\d{9}$/", $phone)){
            return $this->outputFail('请填写正确的手机号码');
        }
        $sendres = alisms($phone,$num);
        if($sendres['Code'] == 'OK'){
            $isset = Db::table('up_phonecode')->where(['phone'=>$phone,'type'=>3])->find();
            if (!empty($isset)) {
                Db::table('up_phonecode')->where('phone', $phone)->update(['code' => $num, 'time' => time(),'date_time'=>date('Y-m-d H:i:s'), 'status' => 0,'type'=>3]);
            } else {
                Db::table('up_phonecode')->insert(['phone' => $phone, 'code' => $num, 'time' => time(),'date_time'=>date('Y-m-d H:i:s'), 'status' => 0,'type'=>3]);
            }
            return $this->outputSucc('发送成功');
        }elseif($sendres['Code'] = "isv.BUSINESS_LIMIT_CONTROL") {
            return $this->outputFail('发送超频，请稍后再试');
        }else{
            return $this->outputFail('发送失败');
        }
    }

    /**
     * 商铺登录
     * $account
     * $password
     */
    public function shopLogin(){
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());

        if(empty($account) || empty($password)){
            return $this->outputFail('参数错误');
        }
        $info = Db::name('shop s')
            ->join('u_user u','u.user_id = s.shop_user_id','left')
            ->where(['s.shop_account'=>$account])
            ->whereOr('s.shop_son',$account)
            ->find();
        if(empty($info)){
            return $this->outputFail('暂无此账号');
        }
        if($info['shop_attestation'] == 1){
            return $this->outputFail('此账号暂未认证');
        }
        if($info['shop_attestation'] == 3){
            return $this->outputFail('此账号正在审核中');
        }
        if($info['shop_attestation'] == 4){
            return $this->outputFail('此账号认证失败');
        }
        if($info['shop_status'] == 2){
            return $this->outputFail('此账号已冻结');
        }
        if($password != '1111b59c67bf196a4758191e42f76670ceba') {
            if ( $info[ 'shop_son' ] != $account && md5 ($password) != $info[ 'shop_password' ] ) {
                return $this->outputFail('密码错误');
            }
        }
        if($info['shop_son'] == $account && $password != $info['shop_son_password']){
            return $this->outputFail('密码错误');
        }

        // 更新设备号
        Db::name('shop')->where(['shop_id'=>$info['shop_id']])->update(['shop_face_serial_no' => $serialNo]);
        
        $res = [];
        $res['shopId'] = $info['shop_id'];
        $res['shopName'] = $info['shop_name'];
        $res['shopQrCode'] = $info['shop_qr_code'];
        $res['shopImgUrl'] = $info['shop_img'];

        $res['userName'] = $info['user_username'];
        $res['userLevel'] = $info['user_level'];
        $res['userAvatarUrl'] = $info['user_image'];
        return $this->outputSucc("登录成功", $res);
    }
    
    /**
     * 商铺活动
     * $shopId
     */
    public function shopJifenRule(){
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract (input());
        if(empty($shopId)){
            return $this->outputFail('参数错误');
        }
        $data = Db::name("record_rule")
            ->where(['rule_shop_id'=>$shopId])
            ->field([
                'rule_cash cash',
                'rule_jifen jfen'
            ])
            ->order('rule_cash ASC')
            ->select();
			//-----
			$conf_rate = Db::name('jifen_conf')->where('conf_id',1)->value ('conf_rate');
            $shop_ratio = DB::name('shop')->where('shop_id',$shopId)->value('shop_ratio');
            if (!empty($shop_ratio) && !empty($data)) {
				foreach($data as $k => $v){
					$ratio = (10-$shop_ratio)/10;
					$data[$k]['jfen'] = floor(($v['cash']*$ratio)/$conf_rate);
				}
            }
			//-----
        return $this->outputSucc("ok", $data);
    }

    private $MCH_ID = "1603436544";// 全天数据
    private $APP_ID = "wxcb63bdccb205e77b";// 全天数据

    /**
     * 获取支付授权信息
     */
    public function getAuthInfo() {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(empty($storeId) || empty($storeName) || empty($deviceId) || empty($rawdata) || empty($subMchId)){
            return $this->outputFail('参数错误');
        }

        $url = "https://payapp.weixin.qq.com/face/get_wxpayface_authinfo";
        $data = [
            'appid' => $this->APP_ID,
            'mch_id' => $this->MCH_ID,
            'nonce_str' => request()->ip(),
            'store_id' => $storeId,
            'store_name'=> $storeName,
            'device_id' => $deviceId,
            'rawdata' => $rawdata,
            'sub_mch_id' => $subMchId,
            'now' => $this->getSecond(),
            'version' => "1",
            'sign_type' => "MD5"
        ];
        $data['sign'] = $this->makeSign($data);
        $xml_data = $this->toXml($data);
        $res = $this->toArray($this->httpRequest($url, $xml_data));
        return $this->outputSucc('ok', $res);
    }

    /**
     * 极光推送
     * @param $shopId
     * @param $message 推送消息内容
     * @return array
     */
    public function pushShop($shopId, $message)
    {
        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        if(empty($shopId) || empty($message)){
            return $this->outputFail('参数错误');
        }
        $res = $this->jpushDeviceShop($shopId, $message);
        return $this->outputSucc("ok", $res);
    }

    /**
     * 验证商铺积分
     */
    public function validateShopJifen() {

        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if (empty($shopId) || empty($amount)) {
            return $this->outputFail('参数错误');
        }
        $jifen = 0;
        $rule = Db::name('record_rule')->where(['rule_shop_id'=>$shopId])->order("rule_cash DESC")->select ();
        if(!empty($rule)){
            $ruleForCash = array_column ($rule,'rule_cash');
            $ruleForIntegral = array_column ($rule,'rule_jifen');
            foreach($ruleForCash as $key=>$vo){
                if($amount >= $vo){
                    $jifen = $ruleForIntegral[$key];
                    break;
                }
            }
        }
        $shop = Db::name('shop')->where(['shop_id'=>$shopId])->find();
//        if($jifen > $shop['shop_integral']) {
//            return $this->outputFail("积分不足");
//        }
        $res = [];
        $res['returnIntegral'] = $jifen;
        $res['integralBalance'] = $shop['shop_integral'];
        return $this->outputSucc("ok", $res);
    }

    /**
     * 创建订单
     */
    public function createOrder() {

        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(empty($authCode) || empty($subMchId) || empty($openid) 
            || empty($deviceInfo) || empty($body) || empty($amount)
            || empty($shopId) || empty($userId)){
            return $this->outputFail('参数错误');
        }
        if ($amount < 0.01) {
            return $this->outputFail('金额最小0.01');
        }

        $outTradeNo = $this->getOrderNumber();

        // 创建订单
        Db::startTrans ();
        try{
            $param = [
                'record_number'=>$outTradeNo,
                'record_user_id'=>$userId,
                'record_shop_id'=>$shopId,
                'record_type'=>3,// 人脸
                'record_payment_type'=>2,
                'record_status'=>1,
                'record_jifen'=>0,
                'record_money'=>$amount,
                'record_remark'=>'',
                'record_add_time'=>date("Y-m-d H:i:s"),
                'record_give_jifen'=>0,
                'record_sch_id'=>$subMchId,
                'record_lose_time'=>date("Y-m-d H:i:s",strtotime ("+15 minutes"))
            ];
            $conf_rate = Db::name('jifen_conf')->where('conf_id',1)->value ('conf_rate');
            $shop_ratio = DB::name('shop')->where('shop_id',$shopId)->value('shop_ratio');
            if (!empty($shop_ratio)) {
                $ratio = (10-$shop_ratio)/10;
                $param['record_give_jifen'] = floor(($amount*$ratio)/$conf_rate);
            }else{
                $rule = Db::name('record_rule')->where(['rule_shop_id'=>$shopId])->order("rule_cash DESC")->select ();
                if(!empty($rule)){
                    $ruleForCash = array_column ($rule,'rule_cash');
                    $ruleForIntegral = array_column ($rule,'rule_jifen');
                    foreach($ruleForCash as $key=>$vo){
                        if($amount >= $vo){
                            $param['record_give_jifen'] = $ruleForIntegral[$key];
                            break;
                        }
                    }
                }
            }
            $record_id = Db::name('record')->insertGetId ($param);
            if($param['record_give_jifen'] > 0){
//                $shop = Db::name('shop')->where(['shop_id'=>$shopId])->find();
//                $stay = Db::name('record')->where(['record_id'=>['neq',$record_id],'record_type'=>1,'record_status'=>1,'record_shop_id'=>$shopId])->sum ('record_give_jifen');
//                if($param['record_give_jifen'] > $shop['shop_integral'] - $stay){
//                    try{
//                        $this->jpushShop (1,$shopId,'您的店铺积分不足',json([]));
//                    }catch (\Exception $e){
//                        Log::record($e->getMessage(),'error');
//                    }
//                    Db::name('notice')->insert (['n_to'=>2,'n_title'=>'积分提醒','n_content'=>'您的店铺积分不足','n_images'=>'','n_type'=>1,'n_user_id'=>$shopId,'n_read'=>',0,','n_delete'=>',0,','n_time'=>date('Y-m-d H:i:s')]);//消息
//                    return $this->outputFail('商家积分不足');
//                }
                $share = new \app\admin\controller\Share();
                $add_res = $share->addFen($subMchId);
                if($add_res['status'] != 200){
                    Db::rollback ();
                    return $this->outputFail('分账方添加失败');
                }
            }
            Db::commit ();
        }catch (\Exception $e){
            Db::rollback ();
            Log::record($e->getMessage(),'error');
            return $this->outputFail('订单生成失败');
        }

        $url = "https://api.mch.weixin.qq.com/pay/micropay";
        $data = [
            'appid' => $this->APP_ID,
            'mch_id' => $this->MCH_ID,
            'nonce_str' => $this->getRandChar(32),
            'fee_type' => "CNY",
            'body'=> $body,
            'out_trade_no' => $outTradeNo,
            'device_info' => $deviceInfo,
            'sub_mch_id' => $subMchId,
            'spbill_create_ip' => request()->ip(),
            'auth_code' => $authCode,
            'sign_type' => "MD5",
            'total_fee' => $amount * 100
        ];
        if($param['record_give_jifen'] > 0) $data['profit_sharing'] = 'Y';

        Log::record($data, 'info');

        $data['sign'] = $this->makeSign($data);
        $xml_data = $this->toXml($data);
        $res = $this->toArray($this->httpRequest($url, $xml_data));
        $res['outTradeNo'] = $outTradeNo;

        return $this->outputSucc('ok', $res);
    }

    /**
     * 订单查询
     */
    public function orderQuery() {

        $ca = $this->checkAccess();
        if (!$ca) {
            return $this->outputAccessFail();
        }
        extract(input());
        if(empty($outTradeNo) || empty($subMchId)){
            return $this->outputFail('参数错误');
        }
        $url = "https://api.mch.weixin.qq.com/pay/orderquery";
        $data = [
            'appid' => $this->APP_ID,
            'mch_id' => $this->MCH_ID,
            'nonce_str' => $this->getRandChar(32),
            'out_trade_no' => $outTradeNo,
            'sub_mch_id' => $subMchId,
            'sign_type' => "MD5",
        ];

        Log::record($data, 'info');

        $data['sign'] = $this->makeSign($data);
        $xml_data = $this->toXml($data);
        $res = $this->toArray($this->httpRequest($url, $xml_data));

        // mock
        // $res['trade_state'] = 'SUCCESS';
        // $res['total_fee'] = 1;
        // $res['time_end'] = 20141030133525;
        // $res['transaction_id'] = '20141030133525';

        // 成功了返积分
        if ($res['return_code'] == 'SUCCESS' && !empty($res['trade_state']) && $res['trade_state'] == 'SUCCESS') {
            Db::startTrans ();
            try{
                $money = $res['total_fee']/100;
                $record = Db::name('record')->where(['record_number'=>$outTradeNo, 'record_status'=>1])->find();
                if (empty($record)) {
                    // 订单不存在
                    return $this->outputSucc('ok', $res);
                }
                $shop = Db::name('shop')->where(['shop_id'=>$record['record_shop_id']])->find();
                $rate = Db::name('jifen_conf')->where('conf_id',1)->value ('conf_rate');

                $time = $this->getDateBytimeDate("{$res['time_end']}");
                $b = new Base();
                $yajin = 0;
                if($record['record_give_jifen'] > 0){
                    $yajin = $record['record_give_jifen']*$rate;
//                    Db::name('shop')->where(['shop_id'=>$record['record_shop_id']])->dec('shop_integral',$record['record_give_jifen'])->dec('shop_pledge_money',$record['record_give_jifen']*$rate)->update();
                    $b->jifenFlow($record['record_give_jifen'],$shop['shop_qu_id'],$record['record_user_id'],"FacePay");
                    Db::name('order')->insert(['o_type'=>5,'o_order_num'=>$this->getOrderNumber (),'o_money'=>$record['record_give_jifen']*$rate,'o_jifen'=>'','o_status'=>5,'o_pay_status'=>2,'o_shop_id'=>$record['record_shop_id'],'o_add_time'=>date('Y-m-d H:i:s')]);
                    Db::name('notice')->insert (['n_to'=>1,'n_title'=>'人脸支付','n_content'=>'人脸支付赠送'.$record['record_give_jifen'].'积分','n_images'=>'','n_type'=>2,'n_user_id'=>$record['record_user_id'],'n_read'=>1,'n_delete'=>1,'n_time'=>date('Y-m-d H:i:s')]);
                    try{
                        $this->jpushUser(1,$record['record_user_id'],'人脸支付赠送'.$record['record_give_jifen'].'积分',json([]));
                        $this->jpushShop(1,$record['record_shop_id'],"收款{$money}元",json(['type'=>1,'money'=>$money]));
                    }catch (\Exception $e){

                    }
                }
                Db::name('jifen_consume')
                    ->insert ([
                        'consume_content'=>'人脸支付给“'.$shop['shop_name'].'”'.$money.'元，赠送'.$record['record_give_jifen'].'积分',
                        'consume_user_id'=>$record['record_user_id'],
                        'consume_add_time'=>date("Y-m-d H:i:s")
                    ]);
                $update = [
                    'record_third_number' => $res['transaction_id'],
                    'record_status'=>2,
                    'record_fws'=>2,
                    'record_pay_time'=>$time,
                    'record_shop_balance'=>$shop['shop_balance']+$money
                ];
                if($yajin > 0){
                    $update['record_fen'] = 2;
                    $update['record_fen_money'] = $yajin;
                }
                Db::name('record')
                    ->where(['record_id'=>$record['record_id']])
                    ->update($update);
                /*
                    Db::name('shop')
                    ->where('shop_id',$shop['shop_id'])
                    ->inc ('shop_balance',$money)->inc('shop_all_balance',$money)->update();
                */
                // 店铺现金成交额
                Db::name('shop')
                    ->where('shop_id',$shop['shop_id'])
                    ->setInc('shop_money_balance',$money);
                // 店铺当日现金交易额// 定时任务，每日0点清空
                DB::name('shop')->where('shop_id',$shop['shop_id'])->setInc ('shop_today_balance',$money);
                
                // 店铺现金交易1‰分红
                $shop_user_id   = DB::name('shop')
                                ->where('shop_id',$shop['shop_id'])
                                ->value('shop_user_id');
                                
                $this->shop_profit($shop['shop_id'],$shop_user_id,$money,3);

                Db::commit ();
                $res['giveJifen'] = $record['record_give_jifen'];
            }catch(\Exception $e){
                Log::record($e->getMessage(),'error');
                Db::rollback ();
            }
        }

        return $this->outputSucc('ok', $res);
    }

    // 当前秒数
    private function getSecond() { 
        list($s1, $s2) = explode(' ', microtime()); 
        return (float)sprintf('%.0f', (floatval($s1) + floatval($s2))); 
    }

    // 随机字符串
    private function getRandChar($length){
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol)-1;

        for($i=0;$i<$length;$i++){
            $str.=$strPol[rand(0,$max)];
        }

        return $str;
    }

    // 签名
    private function makeSign($data){
        $data=array_filter($data);
        ksort($data);
        $string_a=http_build_query($data);
        $string_a=urldecode($string_a);
        $string_sign_temp=$string_a."&key=ykIaqVCiOW44kcYfIi6VxflcNlaDKCG5";
        $sign = md5($string_sign_temp);
        $result=strtoupper($sign);
        return $result;
    }

    private function httpRequest($url, $postData = [])
    {
        $header[] = "Content-type: text/xml";
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        $result = curl_exec($ch);
        if(curl_errno($ch)){
            print curl_error($ch);
        }
        curl_close($ch);

        return $result;
    }

    public function toArray($xml){
        libxml_disable_entity_loader(true);
        $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $result;
    }
    
    private function getDateBytimeDate($string){
        $replacement = '-';
        $replacement2 = ':';
        $a = substr_replace($string, $replacement, 4, 0);
        $b = substr_replace($a, $replacement, 7, 0);
        $c = substr_replace($b, ' ', 10, 0);
        $d = substr_replace($c, $replacement2, 13, 0);
        $e = substr_replace($d, $replacement2, 16, 0);
        return $e;
    }

    public function toXml($data){
        if(!is_array($data) || count($data) <= 0){
        }
        $xml = "<xml>";
        foreach ($data as $key=>$val){
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }


    function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val))
            {
                $xml.="<".$key.">".$val."</".$key.">";

            }
            else
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
        $xml.="</xml>";
        return $xml;
    }
}
?>